/*
 * Copyright (c) 2016. For Intelligent Group.
 */
package com.intelligent.ispc.export.yield;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.intelligent.ispc.common.utils.StringUtils;
import com.intelligent.ispc.constant.AppConstant;
import com.intelligent.ispc.core.dto.YieldDto;
import com.intelligent.ispc.core.dto.YieldHistoryDto;
import com.intelligent.ispc.core.dto.YieldParamDto;
import com.intelligent.ispc.foundation.poi.*;
import com.intelligent.ispc.utils.ExportLabelConstant;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;


import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * fill data to sheet
 *
 * Created by Alice on 2016/9/9.
 */
public class YieldExportWorker implements ExWorker {
    private SXSSFWorkbook workbook = new SXSSFWorkbook(SXSSFWorkbook.DEFAULT_WINDOW_SIZE);
    private List<ExSheet> sheets = new ArrayList<>();
    private Map<String, CellStyle> mapCellStyle = Maps.newHashMap();

    private Integer[] headIndex = new Integer[]{0, 0};
    private Integer[] dataIndex = new Integer[]{0, 1};
    private Integer currentRow = 0;

    /**
     * assemble data in Yield  summary table
     *
     * @param yieldParamDto param of table head
     * @param yieldDtoList  param of summary content data
     */
    public void buildYieldSunmmy(YieldParamDto yieldParamDto, List<YieldDto> yieldDtoList) {

        ExSheet exSheet = new ExSheet();
        mapCellStyle = CellStyleUtil.getStyle(this.getCurrentWorkbook());

        List<ExCell> cellList = Lists.newArrayList();
        List<ExCell> summaryHead = buildSummaryHead(yieldParamDto);
        List<ExCell> summaryContent = buildSummaryContent(yieldDtoList);
        cellList.addAll(summaryHead);
        cellList.addAll(summaryContent);
        exSheet.setExCells(cellList);
        exSheet.setName(AppConstant.YIELD_EXPORT_SUMMARY);
        exSheet.setIndex(0);
        sheets.add(exSheet);
        cellList = null;
        exSheet = null;
    }

    /**
     * assemble data in Yield  summary and detail table
     *
     * @param yieldParamDto    param of table head in Summary table
     * @param yieldDtoList     param of summary content data
     * @param yieldHistoryDtos param of summary and detail content data
     */
    public void buildYieldSunmmyAndDetail(YieldParamDto yieldParamDto, List<YieldDto> yieldDtoList, List<List<YieldHistoryDto>> yieldHistoryDtos) {

        ExSheet exSheet = new ExSheet();
        mapCellStyle = CellStyleUtil.getStyle(this.getCurrentWorkbook());

        List<ExCell> cellList = Lists.newArrayList();
        List<ExCell> summaryHead = buildSummaryHead(yieldParamDto);
        List<ExCell> summaryContent = buildSummaryAndDetailContent(yieldDtoList);
        cellList.addAll(summaryHead);
        cellList.addAll(summaryContent);
        exSheet.setExCells(cellList);
        exSheet.setName(AppConstant.YIELD_EXPORT_SUMMARY);
        exSheet.setIndex(0);
        sheets.add(exSheet);
        cellList = null;
        exSheet = null;

        if (yieldHistoryDtos != null && !yieldHistoryDtos.isEmpty()) {
            for (int i = 0; i < yieldDtoList.size(); i++) {
                ExSheet exSheetItem = new ExSheet();
                List<ExCell> itemsCellList = buildGroupkey(yieldParamDto, yieldHistoryDtos.get(i), yieldDtoList.get(i));
                exSheetItem.setExCells(itemsCellList);
                String groupKey = yieldDtoList.get(i).getGroupKey();
                if (StringUtils.isNotBlank(groupKey)) {
                    if (groupKey.contains(AppConstant.GLOBAL_SEPARATOR)) {
                        groupKey = groupKey.replaceAll(AppConstant.GLOBAL_SEPARATOR, "-");
                    }
                    if (groupKey.contains(":") || groupKey.contains("[") || groupKey.contains("]")
                            || groupKey.contains("*") || groupKey.contains("/") || groupKey.contains("\\")
                            || groupKey.contains("?") || groupKey.contains(" ")) {
                        groupKey = groupKey.replaceAll(":", "_");
                        groupKey = groupKey.replace("[", "_");
                        groupKey = groupKey.replaceAll("]", "_");
                        groupKey = groupKey.replace("*", "_");
                        groupKey = groupKey.replaceAll("/", "_");
                        groupKey = groupKey.replace("\\", "_");
                        groupKey = groupKey.replace("?", "_");
                        groupKey = groupKey.replaceAll(" ", "_");
                    }
                    exSheetItem.setName(groupKey);
                } else {
                    exSheetItem.setName("yield");
                }
                exSheetItem.setIndex(i + 1);
                sheets.add(exSheetItem);
                exSheetItem = null;
                itemsCellList = null;
            }
        }
    }

    private List<ExCell> buildSummaryHead(YieldParamDto yieldParamDto) {
        List<ExCell> exCellList = Lists.newArrayList();
        String testItem = ExportLabelConstant.EXPORT_YIELD_SUMMARY_TESTITEM;
        String usl = ExportLabelConstant.EXPORT_YIELD_SUMMARY_USL;
        String lsl = ExportLabelConstant.EXPORT_YIELD_SUMMARY_LSL;
        String[] title = ExportLabelConstant.EXPORT_YIELD_GROUPKEY_TITLE;
        exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0], headIndex[1]}, testItem, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
        if (yieldParamDto.getTestItemNames() != null && !yieldParamDto.getTestItemNames().isEmpty()) {
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0], headIndex[1] + 1},
                    yieldParamDto.getTestItemNames().get(0), ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0], headIndex[1] + 2},
                    usl, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0], headIndex[1] + 3},
                    yieldParamDto.getUsl() == null ? "" : yieldParamDto.getUsl().toString(), ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0], headIndex[1] + 4},
                    lsl, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0], headIndex[1] + 5},
                    yieldParamDto.getLsl() == null ? "" : yieldParamDto.getLsl().toString(), ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
        } else {
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0], headIndex[1] + 1}, "", ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
        }

        for (int i = 0; i < title.length; i++) {
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + 1, headIndex[0] + i}, title[i], ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_summary_title.toString())));
        }
        title = null;
        return exCellList;
    }

    private List<ExCell> buildSummaryContent(List<YieldDto> yieldDtoList) {
        List<ExCell> exCellList = Lists.newArrayList();
        currentRow = currentRow + 2;

        for (int i = 0; i < yieldDtoList.size(); i++) {
            String groupKey = yieldDtoList.get(i).getGroupKey();
            if (StringUtils.isBlank(groupKey)) {
                groupKey = "-";
            }
            if (groupKey.contains(AppConstant.GLOBAL_SEPARATOR)) {
                groupKey = groupKey.replaceAll(AppConstant.GLOBAL_SEPARATOR, "-");
            }
            String firstInspect = Long.toString(yieldDtoList.get(i).getFirstInspect());
            String firstPass = Long.toString(yieldDtoList.get(i).getFirstPass());
            String firstFail = Long.toString(yieldDtoList.get(i).getFirstFail());
            String fpy = yieldDtoList.get(i).getFpy();
            if (StringUtils.isBlank(fpy)) {
                fpy = "-";
            }
            String reTestInspect = Long.toString(yieldDtoList.get(i).getReTestInspect());
            String reTestPass = Long.toString(yieldDtoList.get(i).getReTestPass());
            String reTestFail = Long.toString(yieldDtoList.get(i).getReTestFail());
            String reTestYield = yieldDtoList.get(i).getReTestYield();
            if (StringUtils.isBlank(reTestYield)) {
                reTestYield = "-";
            }
            String totalYield = yieldDtoList.get(i).getTotalYield();
            if (StringUtils.isBlank(totalYield)) {
                totalYield = "-";
            }

            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1]},
                    groupKey, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 1},
                    firstInspect, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 2},
                    firstPass, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 3},
                    firstFail, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 4},
                    fpy + "%", ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 5},
                    reTestInspect, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 6},
                    reTestPass, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 7},
                    reTestFail, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 8},
                    reTestYield + "%", ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 9},
                    totalYield + "%", ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            currentRow++;
        }
        return exCellList;
    }

    private List<ExCell> buildSummaryAndDetailContent(List<YieldDto> yieldDtoList) {
        List<ExCell> exCellList = Lists.newArrayList();
        String groupKeyName = null;
        currentRow = currentRow + 2;

        for (int i = 0; i < yieldDtoList.size(); i++) {
            String groupKey = yieldDtoList.get(i).getGroupKey();
            if (StringUtils.isBlank(groupKey)) {
                groupKey = "-";
            }
            if (groupKey.contains(AppConstant.GLOBAL_SEPARATOR)) {
                groupKey = groupKey.replaceAll(AppConstant.GLOBAL_SEPARATOR, "-");
            }
            String firstInspect = Long.toString(yieldDtoList.get(i).getFirstInspect());
            String firstPass = Long.toString(yieldDtoList.get(i).getFirstPass());
            String firstFail = Long.toString(yieldDtoList.get(i).getFirstFail());
            String fpy = yieldDtoList.get(i).getFpy();
            if (StringUtils.isBlank(fpy)) {
                fpy = "-";
            }
            String reTestInspect = Long.toString(yieldDtoList.get(i).getReTestInspect());
            String reTestPass = Long.toString(yieldDtoList.get(i).getReTestPass());
            String reTestFail = Long.toString(yieldDtoList.get(i).getReTestFail());
            String reTestYield = yieldDtoList.get(i).getReTestYield();
            if (StringUtils.isBlank(reTestYield)) {
                reTestYield = "-";
            }
            String totalYield = yieldDtoList.get(i).getTotalYield();
            if (StringUtils.isBlank(totalYield)) {
                totalYield = "-";
            }

            if (groupKey == "-") {
                groupKeyName = "yield";
                exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1]},
                        groupKey, ExCellType.HYPERLINK.withCode(ExSheet.formatName(i + 1, groupKeyName)), mapCellStyle.get(CellStyleType.yield_summary_content_groupkey.toString())));
            } else {
                exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1]},
                        groupKey, ExCellType.HYPERLINK.withCode(ExSheet.formatName(i + 1, groupKey)), mapCellStyle.get(CellStyleType.yield_summary_content_groupkey.toString())));
            }

            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 1},
                    firstInspect, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 2},
                    firstPass, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 3},
                    firstFail, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 4},
                    fpy + "%", ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 5},
                    reTestInspect, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 6},
                    reTestPass, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 7},
                    reTestFail, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 8},
                    reTestYield + "%", ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + 9},
                    totalYield + "%", ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            currentRow++;
        }
        return exCellList;
    }

    private List<ExCell> buildGroupkey(YieldParamDto yieldParamDto, List<YieldHistoryDto> yieldHistoryDtoList, YieldDto yieldDto) {
        List<ExCell> exCellList = Lists.newArrayList();
        CellStyle style = null;

        String[] testItem = ExportLabelConstant.EXPORT_YIELD_GROUPKEY_TITLE_ITEM;
        String firstInspect = Long.toString(yieldDto.getFirstInspect());
        String firstPass = Long.toString(yieldDto.getFirstPass());
        String firstFail = Long.toString(yieldDto.getFirstFail());
        String retestInspect = Long.toString(yieldDto.getReTestInspect());
        String retestPass = Long.toString(yieldDto.getReTestPass());
        String retestFail = Long.toString(yieldDto.getReTestFail());
        String uslDetail = ExportLabelConstant.EXPORT_YIELD_DETAIL_USL;
        String lslDetail = ExportLabelConstant.EXPORT_YIELD_DETAIL_LSL;
        String[] arr = {firstInspect, firstPass, firstFail, retestInspect, retestPass, retestFail};

        for (int j = 0; j < arr.length; j++) {
            if (StringUtils.isBlankWithSpecialNumber(arr[j]) || ("Infinity").equals(arr[j])) {
                arr[j] = "-";
            }
        }

        if (yieldParamDto.getTestItemNames() != null) {
            String uslvalue = yieldParamDto.getUsl() == null ? " " : yieldParamDto.getUsl().toString();
            String lslvalue = yieldParamDto.getLsl() == null ? " " : yieldParamDto.getLsl().toString();
            exCellList.add(ExUtil.fillToCell(new Integer[]{dataIndex[0], dataIndex[1] + 6},
                    uslDetail + "=" + uslvalue + "," + lslDetail + "=" + lslvalue, ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
        }

        currentRow = 0;
        for (int i = 0; i < yieldHistoryDtoList.size(); i++) {
            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1]},
                    testItem[i], ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            exCellList.add(ExUtil.fillToCell(new Integer[]{dataIndex[0] + currentRow, dataIndex[1]},
                    arr[i], ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));

            currentRow++;
            for (int q = 0; q < yieldHistoryDtoList.get(i).getColumnNames().length; q++) {
                String[] columnNames = yieldHistoryDtoList.get(i).getColumnNames();
                style = mapCellStyle.get(CellStyleType.groupKey_table_up.toString());
                if (q == 0) {
                    style = mapCellStyle.get(CellStyleType.groupKey_table_up_l.toString());
                }
                if (q == yieldHistoryDtoList.get(i).getColumnNames().length - 1) {
                    style = mapCellStyle.get(CellStyleType.groupKey_table_up_r.toString());
                }
                exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + q}, columnNames[q], ExCellType.TEXT, style));
            }

            currentRow++;
            if ((yieldHistoryDtoList.get(i).getColumnValues() != null && !yieldHistoryDtoList.get(i).getColumnValues().isEmpty()) && arr[i] != "0") {
                for (int j = 0; j < yieldHistoryDtoList.get(i).getColumnValues().size(); j++) {
                    int size = yieldHistoryDtoList.get(i).getColumnValues().size() - 1;
                    if (j == size) {
                        String[] lastRowValues = yieldHistoryDtoList.get(i).getColumnValues().get(size);

                        for (int k = 0; k < lastRowValues.length; k++) {
                            style = mapCellStyle.get(CellStyleType.groupKey_table_down.toString());
                            if (k == 0) {
                                style = mapCellStyle.get(CellStyleType.groupKey_table_down_l.toString());
                            }
                            if (k == yieldHistoryDtoList.get(i).getColumnNames().length - 1) {
                                style = mapCellStyle.get(CellStyleType.groupKey_table_down_r.toString());
                            }
                            if (StringUtils.isBlank(lastRowValues[k])) {
                                lastRowValues[k] = "-";
                            }
                            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + k}, lastRowValues[k], ExCellType.TEXT, style));
                        }
                    } else {
                        for (int m = 0; m < yieldHistoryDtoList.get(i).getColumnValues().get(0).length; m++) {
                            String[] columnValue = yieldHistoryDtoList.get(i).getColumnValues().get(j);
                            if (StringUtils.isBlank(columnValue[m])) {
                                columnValue[m] = "-";
                            }
                            style = mapCellStyle.get(CellStyleType.yield_content_font.toString());
                            if (m == 0) {
                                style = mapCellStyle.get(CellStyleType.groupKey_table_left.toString());
                            }
                            if (m == yieldHistoryDtoList.get(i).getColumnValues().get(0).length - 1) {
                                style = mapCellStyle.get(CellStyleType.groupKey_table_right.toString());
                            }
                            exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + m}, columnValue[m], ExCellType.TEXT, style));

                        }
                    }

                    currentRow++;
                }
            } else {
                for (int k = 0; k < yieldHistoryDtoList.get(i).getColumnNames().length; k++) {
                    if (k == 0) {
                        style = mapCellStyle.get(CellStyleType.groupKey_table_down_l.toString());
                        exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + k}, "No Data", ExCellType.TEXT, style));
                    } else {
                        style = mapCellStyle.get(CellStyleType.groupKey_table_down.toString());
                        if (k == yieldHistoryDtoList.get(i).getColumnNames().length - 1) {
                            style = mapCellStyle.get(CellStyleType.groupKey_table_down_r.toString());
                        }
                        exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + k}, " ", ExCellType.TEXT, style));
                    }
                }
                currentRow++;
            }
            for (int k = 0; k < yieldHistoryDtoList.get(i).getColumnNames().length; k++) {
                exCellList.add(ExUtil.fillToCell(new Integer[]{headIndex[0] + currentRow, headIndex[1] + k}, " ", ExCellType.TEXT, mapCellStyle.get(CellStyleType.yield_content_font.toString())));
            }
            currentRow++;
        }
        arr = null;
        testItem = null;

        return exCellList;
    }


    private String formatDouble(double str, int dig) {
        return String.format("%." + dig + "f", str);
    }


    @Override
    public SXSSFWorkbook getCurrentWorkbook() {
        return workbook;
    }


    @Override
    public List<ExSheet> getSheets() {
        return sheets;
    }
}
